package model;

import inf.minife.fe.Constraint;
import inf.minife.fe.DOF;
import inf.minife.fe.Force;
import inf.minife.fe.Model;
import inf.minife.fe.Realtable;
import inf.minife.fe.Truss2D;

/*
 * In this program, we use plane truss model
 * with 10 truss elements and 6 nodes
 * follow the model of Rajeev and Krishnamoorthy
 * "Discrete optimization of structure using genetic algorithm"
 */

public class PlaneTruss {
	private Model model;

	public static void main(String[] args) {
		Model model = new PlaneTruss().getModel();

		model.printStructure();
		model.solve();
		
		model.printResults();
		
		double mass = model.getTotalMass();
		
		System.out.println("Total Mass = " + mass);
		//Viewer2 viewer = new Viewer2(model);
		//viewer.setVisible(true);
	}

	public PlaneTruss() {

		// model
		model = new Model();
		/*
		 * E = 1x 10^4 ksi (6.89 x 10^4 MPa)
		 * rho = 0.10 lb/in^3 (2,770 kg/m^3)
		 * H = B = 360 in 
		 * P = 100 kips (445.374 kN)
		 */
		double E = 1E4; // N/mm^2 (modulus of elasticity)
		double rho = 0.10; // kg/mm^2 (density of steel)
		model.createMaterial(1, E, rho);
		
		double[] arrayA = {	30.0, 1.62, 22.90, 13.50, 1.62,
							1.62, 13.90, 22.00, 22.00, 1.62};
		
		for (int i = 1; i <= 10; i++) {
			//double A = 30.0; // in^2
			double A = arrayA[i-1];
			Realtable r = model.createRealtable(i, Truss2D.TYPE);
			//r.setValue(TrussElement.RT_A, A);
			r.setValue(Truss2D.RT_A, A);
			//r.setValue(idx, value)
			//System.out.println("Element [" + i + "] has area = " + r.getValue(Truss2D.RT_A));
		}

		double B = 360; // 360 in
		model.createNode(6, 0, 0, 0);
		model.createNode(4, B, 0, 0);
		model.createNode(2, 2*B, 0, 0);
		model.createNode(5, 0, B, 0);
		model.createNode(3, B, B, 0);
		model.createNode(1, 2*B, B, 0);

		// forces
		Force f = new Force();
		f.setValue(DOF.T_Y, -100.0); // 100 kips = 445.374 kN
		model.getNode(4).setForce(f);
		model.getNode(2).setForce(f);

		// constraints
		Constraint c = new Constraint();
		c.setFree(DOF.T_X, false);
		c.setFree(DOF.T_Y, false);
		model.getNode(6).setConstraint(c);
		model.getNode(5).setConstraint(c);

		// 10 elements
		model.createElement(1, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(1), model.getNode(5), model.getNode(3));
		model.createElement(2, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(2), model.getNode(3), model.getNode(1));
		model.createElement(3, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(3), model.getNode(6), model.getNode(4));
		model.createElement(4, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(4), model.getNode(4), model.getNode(2));
		model.createElement(5, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(5), model.getNode(3), model.getNode(4));
		model.createElement(6, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(6), model.getNode(1), model.getNode(2));
		model.createElement(7, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(7), model.getNode(5), model.getNode(4));
		model.createElement(8, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(8), model.getNode(6), model.getNode(3));
		model.createElement(9, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(9), model.getNode(3), model.getNode(2));
		model.createElement(10, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(10), model.getNode(4), model.getNode(1));
	}
	public Model createModel(double[] x){
		// model
		model = new Model();
		/*
		 * E = 1x 10^4 ksi (6.89 x 10^4 MPa)
		 * rho = 0.10 lb/in^3 (2,770 kg/m^3)
		 * H = B = 360 in 
		 * P = 100 kips (445.374 kN)
		 */
		double E = 1E4; // N/mm^2 (modulus of elasticity)
		double rho = 0.10; // kg/mm^2 (density of steel)
		model.createMaterial(1, E, rho);
		
		//double[] arrayA = {	30.0, 1.62, 22.90, 13.50, 1.62,
		//					1.62, 13.90, 22.00, 22.00, 1.62};
		
		for (int i = 1; i <= x.length; i++) {
			//double A = 30.0; // in^2
			double a = x[i-1];
			Realtable r = model.createRealtable(i, Truss2D.TYPE);
			//r.setValue(TrussElement.RT_A, A);
			r.setValue(Truss2D.RT_A, a);
			//r.setValue(idx, value)
			System.out.println("Element [" + i + "] has area = " + r.getValue(Truss2D.RT_A));
		}
		
		double B = 360; // 360 in
		model.createNode(6, 0, 0, 0);
		model.createNode(4, B, 0, 0);
		model.createNode(2, 2*B, 0, 0);
		model.createNode(5, 0, B, 0);
		model.createNode(3, B, B, 0);
		model.createNode(1, 2*B, B, 0);

		// forces
		Force f = new Force();
		f.setValue(DOF.T_Y, -100.0); // 100 kips = 445.374 kN
		model.getNode(4).setForce(f);
		model.getNode(2).setForce(f);

		// constraints
		Constraint c = new Constraint();
		c.setFree(DOF.T_X, false);
		c.setFree(DOF.T_Y, false);
		model.getNode(6).setConstraint(c);
		model.getNode(5).setConstraint(c);

		// 10 elements
		model.createElement(1, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(1), model.getNode(5), model.getNode(3));
		model.createElement(2, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(2), model.getNode(3), model.getNode(1));
		model.createElement(3, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(3), model.getNode(6), model.getNode(4));
		model.createElement(4, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(4), model.getNode(4), model.getNode(2));
		model.createElement(5, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(5), model.getNode(3), model.getNode(4));
		model.createElement(6, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(6), model.getNode(1), model.getNode(2));
		model.createElement(7, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(7), model.getNode(5), model.getNode(4));
		model.createElement(8, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(8), model.getNode(6), model.getNode(3));
		model.createElement(9, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(9), model.getNode(3), model.getNode(2));
		model.createElement(10, Truss2D.TYPE, model.getMaterial(1), model
				.getRealtable(10), model.getNode(4), model.getNode(1));
		
		return model;
	}
	public Model getModel() {
		return model;
	}
}
